import { describe, expect, it } from 'vitest'
import { shallowRef } from 'vue'
import { useCounter } from './index'

describe('useCounter', () => {
  it('should be defined', () => {
    expect(useCounter).toBeDefined()
  })

  it('should be update counter', () => {
    const { count, inc, dec, get, set, reset } = useCounter()

    expect(count.value).toBe(0)
    expect(get()).toBe(0)
    inc()
    expect(count.value).toBe(1)
    expect(get()).toBe(1)
    inc(2)
    expect(count.value).toBe(3)
    expect(get()).toBe(3)
    inc(-1)
    expect(count.value).toBe(2)
    expect(get()).toBe(2)
    dec()
    expect(count.value).toBe(1)
    expect(get()).toBe(1)
    dec(5)
    expect(count.value).toBe(-4)
    expect(get()).toBe(-4)
    dec(-1)
    expect(count.value).toBe(-3)
    expect(get()).toBe(-3)
    set(100)
    expect(count.value).toBe(100)
    expect(get()).toBe(100)
    reset()
    expect(count.value).toBe(0)
    expect(get()).toBe(0)
    reset(25)
    expect(count.value).toBe(25)
    expect(get()).toBe(25)
    reset()
    expect(count.value).toBe(25)
    expect(get()).toBe(25)
  })

  it('should be update initial & counter', () => {
    const initial = shallowRef(0)
    const { count, inc, dec, get, set, reset } = useCounter(initial)

    expect(count.value).toBe(0)
    expect(initial.value).toBe(0)
    expect(get()).toBe(0)
    inc()
    expect(initial.value).toBe(1)
    expect(count.value).toBe(1)
    expect(get()).toBe(1)
    inc(2)
    expect(count.value).toBe(3)
    expect(initial.value).toBe(3)
    expect(get()).toBe(3)
    dec()
    expect(count.value).toBe(2)
    expect(initial.value).toBe(2)
    expect(get()).toBe(2)
    dec(5)
    expect(count.value).toBe(-3)
    expect(initial.value).toBe(-3)
    expect(get()).toBe(-3)
    set(100)
    expect(count.value).toBe(100)
    expect(initial.value).toBe(100)
    expect(get()).toBe(100)
    reset()
    expect(count.value).toBe(0)
    expect(initial.value).toBe(0)
    expect(get()).toBe(0)
    reset(25)
    expect(count.value).toBe(25)
    expect(initial.value).toBe(25)
    expect(get()).toBe(25)
    reset()
    expect(count.value).toBe(25)
    expect(initial.value).toBe(25)
    expect(get()).toBe(25)
  })

  it('should be update limited counter', () => {
    const { count, inc, dec, get, set, reset } = useCounter(1, { min: -2, max: 15 })

    expect(count.value).toBe(1)
    expect(get()).toBe(1)
    inc(20)
    expect(count.value).toBe(15)
    expect(get()).toBe(15)
    inc(-20)
    expect(count.value).toBe(-2)
    expect(get()).toBe(-2)
    dec(-20)
    expect(count.value).toBe(15)
    expect(get()).toBe(15)
    dec(2)
    expect(count.value).toBe(13)
    expect(get()).toBe(13)
    dec()
    expect(count.value).toBe(12)
    expect(get()).toBe(12)
    dec(20)
    expect(count.value).toBe(-2)
    expect(get()).toBe(-2)
    reset()
    expect(count.value).toBe(1)
    expect(get()).toBe(1)
    set(20)
    expect(count.value).toBe(15)
    expect(get()).toBe(15)
    set(-10)
    expect(count.value).toBe(-2)
    expect(get()).toBe(-2)
    reset()
    expect(count.value).toBe(1)
    expect(get()).toBe(1)
    reset(20)
    expect(count.value).toBe(15)
    expect(get()).toBe(15)
    reset(-10)
    expect(count.value).toBe(-2)
    expect(get()).toBe(-2)
  })
})
